#include "NiceTry2Solver.hpp"
#include <cstdlib>
#include <algorithm>

void	NiceTry2Solver::execute() EXC_THROWER()
{
	EXC_RETHROW_BEGIN()
	{
        VNDTry  vnd(soVRPTW);
        SolutionEval    evalsol;
        SolutionEval    evalsolbest;
        unsigned        iteration = 0;
        unsigned        amelioration = 0;
        unsigned        amelioration_iteration = 0;
        // I. Initialisation
        // 1. creer une solution basique
        Solution        sol(soVRPTW);
        sol.complete();
        
        
        nsBestSolution = sol;
        nsBestSolution.eval(&evalsolbest);
        
        std::cout << "starting from..." << std::endl;
        std::cout << nsBestSolution.toString() << std::endl;
        std::cout << evalsolbest.toString() << std::endl;
        
        for (;; iteration++)
        {        
            // 4. executer le merger
            nsMerger.execute();
            //std::cout << nsMerger.getBestSolution().toString() << std::endl;

            
            // 5. executer la vnd depuis la solution du merger
            vnd.execute(nsMerger.getBestSolution(), (iteration - amelioration_iteration) << 5);
            
            // 6. evaluer la solution de la vnd
            vnd.getBestSolution().eval(&evalsol);
            
            if (evalsol < evalsolbest)
            {
                amelioration++;
                nsBestSolution = vnd.getBestSolution();
                evalsolbest = evalsol;
                amelioration_iteration = iteration;
                
                nsMerger.getTable().clear();
                vnd.getBestSolution().fillDeque(nsMerger.getTable());
                
                std::cout << nsBestSolution.toString() << std::endl;
                std::cout << evalsolbest.toString() << std::endl;
                std::cout << "amelioration " << amelioration << "@" << iteration << std::endl;
            }
            else
            {
                for (unsigned i = 0 ; i < ((iteration - amelioration_iteration) << 1) ; i++)
                {
                    unsigned pred_sol1, pred_sol2, cur;
                    
                    pred_sol1 = rand() % nsMerger.getTable().size();
                    pred_sol2 = rand() % nsMerger.getTable().size();
                
                    cur = nsMerger.getTable()[pred_sol2];
                    nsMerger.getTable()[pred_sol2] = nsMerger.getTable()[pred_sol1];
                    nsMerger.getTable()[pred_sol1] = cur;
                }
            }
        }
	}
	EXC_RETHROW_END()
}
